﻿using System;
using System.Collections.Generic;
using System.Text;

namespace MLForgeSharp.Models.SupervisedLearningModels.Linear
{
    /// <summary>
    /// 逻辑回归模型
    /// </summary>
    public class LogiRegModel
    {
        private double[] weights; // 权重向量
        private double bias; // 偏置项
        private double learningRate; // 学习率
        private int maxIterations; // 最大迭代次数

        public LogiRegModel(double learningRate = 0.01, int maxIterations = 1000)
        {
            this.learningRate = learningRate;
            this.maxIterations = maxIterations;
        }

        // Sigmoid 函数
        private double Sigmoid(double z)
        {
            return 1.0 / (1.0 + Math.Exp(-z));
        }

        // 训练模型
        public void Train(double[][] data, int[] targets)
        {
            int numSamples = data.Length;
            int numFeatures = data[0].Length;
            weights = new double[numFeatures];
            bias = 0.0;

            for (int iter = 0; iter < maxIterations; iter++)
            {
                double[] gradientsWeights = new double[numFeatures];
                double gradientBias = 0.0;

                for (int i = 0; i < numSamples; i++)
                {
                    double prediction = PredictProbability(data[i]);
                    double error = prediction - targets[i];

                    for (int j = 0; j < numFeatures; j++)
                    {
                        gradientsWeights[j] += error * data[i][j];
                    }
                    gradientBias += error;
                }

                for (int j = 0; j < numFeatures; j++)
                {
                    weights[j] -= learningRate * gradientsWeights[j] / numSamples;
                }
                bias -= learningRate * gradientBias / numSamples;
            }
        }

        // 预测概率
        public double PredictProbability(double[] features)
        {
            double z = bias;
            for (int i = 0; i < features.Length; i++)
            {
                z += weights[i] * features[i];
            }
            return Sigmoid(z);
        }

        // 预测类别
        public int Predict(double[] features)
        {
            double probability = PredictProbability(features);
            return probability > 0.5 ? 1 : 0;
        }
    }

    // 示例程序
    public class LogiRegModelExample
    {
        public LogiRegModelExample()
        {
            // 示例数据
            double[][] data = new double[][]
        {
            new double[] { 1.0, 2.0 },
            new double[] { 1.1, 2.1 },
            new double[] { 1.2, 2.2 },
            new double[] { 1.3, 2.3 },
            new double[] { 10.0, 10.0 },
            new double[] { 10.1, 10.1 }
        };

            int[] targets = { 0, 0, 0, 0, 1, 1 }; // 目标类别

            // 创建模型
            LogiRegModel model = new LogiRegModel(learningRate: 0.01, maxIterations: 1000);

            // 训练模型
            model.Train(data, targets);

            // 预测
            double[] testFeatures = { 1.0, 2.0 };
            int predictedClass = model.Predict(testFeatures);

            System.Console.WriteLine("预测类别: " + predictedClass);
        }
    }
}
